import 'dart:ui';

import 'package:flutter_graphics_view/src/context/scene_model_context.dart';
import 'package:flutter_graphics_view/src/context/scene_state_context.dart';
import 'package:flutter_graphics_view/src/model/item_model_data.dart';

class ModelWriter {
  final SceneModelContext sceneModelContext;
  final SceneStateContext sceneStateContext;

  ModelWriter(this.sceneModelContext, this.sceneStateContext);
}

mixin ItemWriter on ModelWriter {
  setItemParent(String itemId, String parentId) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    assert(sceneModelContext.itemExists(parentId), '场景中不存在ID=$parentId的模型');
    removeItemParent(itemId);
    if (_checkParentChildLoop(itemId, parentId)) {
      sceneModelContext.getItem(itemId).setParent(parentId);
      sceneModelContext.getItem(parentId).addChild(itemId);
    }
  }

  removeItemParent(String itemId) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    final parentId = sceneModelContext.getItem(itemId).parentId;
    if (null != parentId) {
      sceneModelContext.getItem(itemId).removeParent();
      sceneModelContext.getItem(parentId).removeChild(itemId);
    }
  }

  _removeParentFromChildren(String itemId) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    final itemModelData = sceneModelContext.getItem(itemId);
    final childrenToRemove = List.from(itemModelData.childrenIds);
    childrenToRemove.forEach((childId) {
      removeItemParent(childId);
    });
  }

  updateItem(String itemId) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    sceneModelContext.getItem(itemId).updateItem();
  }

  setItemPosition(String itemId, Offset position) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    sceneModelContext.getItem(itemId).setPosition(position);
  }

  moveItem(String itemId, Offset offset) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    sceneModelContext.getItem(itemId).move(offset / sceneStateContext.scale);
  }

  moveItemWithChildren(String itemId, Offset offset) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    moveItem(itemId, offset);
    sceneModelContext.getItem(itemId).childrenIds.forEach((childId) {
      moveItemWithChildren(childId, offset);
    });
  }

  setItemZOrder(String itemId, int zOrder) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    sceneModelContext.setItemZOrder(itemId, zOrder);
  }

  int moveItemToTop(String itemId) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    return sceneModelContext.moveItemToTop(itemId);
  }

  int moveItemToTopWithChildren(String itemId) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    int zOrder = moveItemToTop(itemId);
    _setZOrderToChildren(itemId, zOrder);
    return zOrder;
  }

  int moveItemToBottom(String itemId) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    return sceneModelContext.moveItemToBottom(itemId);
  }

  int moveItemToBottomWithChildren(String itemId) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    int zOrder = moveItemToBottom(itemId);
    _setZOrderToChildren(itemId, zOrder);
    return zOrder;
  }

  resizeItem(String itemId, Offset deltaSize) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    sceneModelContext.getItem(itemId).resizeDelta(deltaSize);
  }

  setItemSize(String itemId, Size size) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    sceneModelContext.getItem(itemId).setSize(size);
  }

  _setZOrderToChildren(String itemId, int zOrder) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    setItemZOrder(itemId, zOrder);
    sceneModelContext.getItem(itemId).childrenIds.forEach((childId) {
      _setZOrderToChildren(childId, zOrder + 1);
    });
  }

  bool _checkParentChildLoop(String itemId, String parentId) {
    if (itemId == parentId) {
      return false;
    }
    final ppid = sceneModelContext.getItem(parentId).parentId;
    if (null != ppid) {
      return _checkParentChildLoop(itemId, ppid);
    }
    return true;
  }
}

class SceneModelWriter extends ModelWriter with ItemWriter {
  SceneModelWriter(super.sceneModelContext, super.sceneStateContext);

  String addItem(ItemModelData itemData) {
    return sceneModelContext.addItem(itemData);
  }

  removeItem(String itemId) {
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    removeItemParent(itemId);
    _removeParentFromChildren(itemId);
    sceneModelContext.removeItem(itemId);
  }

  removeItemWithChildren(String itemId){
    assert(sceneModelContext.itemExists(itemId), '场景中不存在ID=$itemId的模型');
    List<String> itemsToRemove = [];
    _removeItemWithChildrenRecursive(itemId,itemsToRemove);
    itemsToRemove.reversed.forEach(removeItem);
  }

  _removeItemWithChildrenRecursive(String itemId,List<String> childs){
    childs.add(itemId);
    sceneModelContext.getItem(itemId).childrenIds.forEach((element) {
      _removeItemWithChildrenRecursive(element, childs);
    });
  }

  removeAllItems(){
    sceneModelContext.removeAllItems();
  }
}
